//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//

#include <bsp.h>
#include <boot.h>
#include "xllp_keypad.h"

//------------------------------------------------------------------------------

#define KEYPAD_COOKIE               'KeyP'

//------------------------------------------------------------------------------

typedef struct KEYPAD {
    UINT32 cookie;                  // Cookie to verify handler
} KEYPAD;

//------------------------------------------------------------------------------

static
KEYPAD
s_keypad;

//------------------------------------------------------------------------------

BOOL
BootKeypadLittletonDeinit(
    HANDLE hKeypad
    );

BOOL
BootKeypadLittletonIoCtl(
    HANDLE hKeypad,
    DWORD code,
    VOID* pBuffer,
    DWORD size
    );

//------------------------------------------------------------------------------

static
BOOL
KeypadPressed(
    KEYPAD* pKeypad,
    UINT16 vk
    );

//------------------------------------------------------------------------------

static BOOT_DEVICE_IFC s_keypadIfc = {
    &s_keypad,
    BootKeypadLittletonDeinit,
    NULL,
    NULL,
    NULL,
    NULL,
    BootKeypadLittletonIoCtl
};

//------------------------------------------------------------------------------

volatile unsigned int         * g_vpKeypadRegs = (volatile unsigned int *) MONAHANS_BASE_REG_PA_KEYPAD;
volatile XLLP_CLKMGR_T  * g_vpClkRegs        = (volatile XLLP_CLKMGR_T *) MONAHANS_BASE_REG_PA_CLKMGR;
volatile unsigned int         * g_vpOSTRegs       = (volatile unsigned int *) MONAHANS_BASE_REG_PA_OST;
volatile unsigned int         * g_vpMFPRegs       = (volatile unsigned int *) MONAHANS_BASE_REG_PA_MFP;

//------------------------------------------------------------------------------

#define XLLP_KP_MAX_SINGLE_SCAN_CODES 35

UINT8 MatrixToXllpScanCodeTable[XLLP_KP_MAX_SINGLE_SCAN_CODES] = 
{
        /*IN0*/ 
/*OUT0 */XLLP_KP_SC_1,    
/*OUT1 */XLLP_KP_SC_4,    
/*OUT2 */XLLP_KP_SC_7,    
/*OUT3 */XLLP_KP_SC_STAR, 
/*OUT4 */XLLP_KP_SC_NO_KEY,  

        /*IN1*/ 
/*OUT0 */XLLP_KP_SC_2,    
/*OUT1 */XLLP_KP_SC_5,    
/*OUT2 */XLLP_KP_SC_8,    
/*OUT3 */XLLP_KP_SC_0,    
/*OUT4 */XLLP_KP_SC_NO_KEY,     

        /*IN2*/ 
/*OUT0 */XLLP_KP_SC_3,    
/*OUT1 */XLLP_KP_SC_6,    
/*OUT2 */XLLP_KP_SC_9,    
/*OUT3 */XLLP_KP_SC_POUND,
/*OUT4 */XLLP_KP_SC_NO_KEY,     

        /*IN3*/ 
/*OUT0 */XLLP_KP_SC_SOFT1, 
/*OUT1 */XLLP_KP_SC_SOFT2, 
/*OUT2 */XLLP_KP_SC_SEND,  
/*OUT3 */XLLP_KP_SC_END,  
/*OUT4 */XLLP_KP_SC_NO_KEY,     

        /*IN4*/ 
/*OUT0 */XLLP_KP_SC_HOME,  
/*OUT1 */XLLP_KP_SC_DELETE,   
/*OUT2 */XLLP_KP_SC_VOL_UP,
/*OUT3 */XLLP_KP_SC_VOL_DN, 
/*OUT4*/XLLP_KP_SC_NO_KEY,   

        /*IN5*/ 
/*OUT0 */XLLP_KP_SC_N_UP,    
/*OUT1 */XLLP_KP_SC_N_DOWN,
/*OUT2 */XLLP_KP_SC_N_LEFT, 
/*OUT3 */XLLP_KP_SC_N_RIGHT, 
/*OUT4 */XLLP_KP_SC_N_ACTION, 

		/*6 Direct Keys*/ 
/*DKEY0 */XLLP_KP_SC_SCROLL_UP,          
/*DKEY1 */XLLP_KP_SC_SCROLL_DOWN,
/*DKEY2 */XLLP_KP_SC_INVALID_KEY, 
/*DKEY3 */XLLP_KP_SC_INVALID_KEY,     
/*DKEY4 */XLLP_KP_SC_INVALID_KEY
};  /*xllpKpScanCodeLutLower*/

#define XLLP_SCAN_CODE_MAX 0xBF

const UINT8  XllpScanCodeToMainScanCodeTable[XLLP_SCAN_CODE_MAX+1] =
{
	0x10,// 'A',	    // Xllp Scan Code 0x0  
	0x16,//'G',			// Xllp Scan Code 0x1  
	0x1C,//'M',			// Xllp Scan Code 0x2  
	0x22,//'S',			// Xllp Scan Code 0x3
	0x80, 		        // Xllp Scan Code 0x4  
	0x3A,//VK_THOME,	// Xllp Scan Code 0x5
	0x41,//VK_TUP,		// Xllp Scan Code 0x6  
	0xFF,				// Xllp Scan Code 0x7
	0xFF,				// Xllp Scan Code 0x8  
	0xFF,				// Xllp Scan Code 0x9
	0x41, //0x43,//VK_TVOLUMEUP,	// Xllp Scan Code 0xA  	
	0x38, //0x42,//VK_TVOLUMEDOWN,	// Xllp Scan Code 0xB  
	0x36,//VK_TACTION,		// Xllp Scan Code 0xC  
	0x45,//VK_Record	// Xllp Scan Code 0xD
	0xFF,				// Xllp Scan Code 0xE  
	0xFF,				// Xllp Scan Code 0xF

	0x11,//'B',							// Xllp Scan Code 0x10 
	0x17,//'H',							// Xllp Scan Code 0x11 
	0x1D,//'N',							// Xllp Scan Code 0x12 
	0x23,//'T',							// Xllp Scan Code 0x13
	0x81,  		        					// Xllp Scan Code 0x14
	0x32,//VK_CAPITAL-->SHIFT(caps)			// Xllp Scan Code 0x15
	0x38,//VK_TDOWN,   					// Xllp Scan Code 0x16
	0xFF,								// Xllp Scan Code 0x17
	0xFF,								// Xllp Scan Code 0x18
	0x8A,      //VK_Contacts and "("  			//Xllp Scan code 0x19
	0x8E,	//VK_Calendar and ")"			// Xllp Scan Code 0x1A
	0x8B,	//VK_LAUNCH_MAIL and "!"      	// Xllp Scan Code 0x1B
    0x8F,      //VK_BACK and VK_ENTER           // Xllp Scan Code 0x1C
	0x43,	//VK_XLLP_KP_SC_VOL_UP		// Xllp Scan Code 0x1D
	0x42,	//VK_XLLP_KP_SC_VOL_DN		// Xllp Scan Code 0x1E
    0xFF,                               // Xllp Scan Code 0x1F

    0x12,//'C',         // Xllp Scan Code 0x20
    0x18,//'I',         // Xllp Scan Code 0x21
    0x1E,//'O',         // Xllp Scan Code 0x22
    0x24,//'U',         // Xllp Scan Code 0x23
    0x28,//'Y',         // Xllp Scan Code 0x24
    0x35,//VK_SPACE,           // Xllp Scan Code 0x25
    0x3B,//VK_TLEFT,           // Xllp Scan Code 0x26
    0xFF,               // Xllp Scan Code 0x27
    0xFF,               // Xllp Scan Code 0x28
    0xFF,               // Xllp Scan Code 0x29
    0xFF,               // Xllp Scan Code 0x2A
    0xFF,               // Xllp Scan Code 0x2B
    0xFF,               // Xllp Scan Code 0x2C
    0xFF,               // Xllp Scan Code 0x2D
    0xFF,               // Xllp Scan Code 0x2E
    0xFF,               // Xllp Scan Code 0x2F

    0x13,//'D',         // Xllp Scan Code 0x30
    0x19,//'J',         // Xllp Scan Code 0x31
    0x1F,//'P',         // Xllp Scan Code 0x32
    0x25,//'V',         // Xllp Scan Code 0x33
    0x29,//'Z',         // Xllp Scan Code 0x34
    0x35, //VK_SPACE        // xllp scan code 0x35
    
    0x34,//VK_TRIGHT        // Xllp Scan Code 0x36
    0xFF,               // Xllp Scan Code 0x37
    0xFF,               // Xllp Scan Code 0x38
    0xFF,               // Xllp Scan Code 0x39
    0xFF,               // Xllp Scan Code 0x3A
    0xFF,               // Xllp Scan Code 0x3B
    0xFF,               // Xllp Scan Code 0x3C
    0xFF,               // Xllp Scan Code 0x3D
    0xFF,               // Xllp Scan Code 0x3E
    0xFF,               // Xllp Scan Code 0x3F

    0x14,//'E',         // Xllp Scan Code 0x40  
    0x1A,//'K',         // Xllp Scan Code 0x41  
    0x20,//'Q',         // Xllp Scan Code 0x42  
    0x26,//'W',         // Xllp Scan Code 0x43  
    0x82,                   // Xllp Scan Code 0x44  
    0x33,//VK_CONTROL,  // Xllp Scan Code 0x45
    0x36,//VK_TACTION,  // Xllp Scan Code 0x46  
    0xFF,               // Xllp Scan Code 0x47
    0xFF,               // Xllp Scan Code 0x48  
    0xFF,               // Xllp Scan Code 0x49
    0xFF,               // Xllp Scan Code 0x4A  
    0xFF,               // Xllp Scan Code 0x4B  
    0xFF,               // Xllp Scan Code 0x4C  
    0xFF,               // Xllp Scan Code 0x4D
    0xFF,               // Xllp Scan Code 0x4E
    0xFF,               // Xllp Scan Code 0x4F

    0x15,//'F',         // Xllp Scan Code 0x50  
    0x1B,//'L',         // Xllp Scan Code 0x51  
    0x21,//'R',         // Xllp Scan Code 0x52  
    0x27,//'X',         // Xllp Scan Code 0x53
    0x83,               // Xllp Scan Code 0x54
    0x39,//VK_TEND,    // Xllp Scan Code 0x55
    0xFF,               // Xllp Scan Code 0x56
    0xFF,               // Xllp Scan Code 0x57
    0xFF,               // Xllp Scan Code 0x58
    0xFF,               // Xllp Scan Code 0x59
    0xFF,               // Xllp Scan Code 0x5A
    0xFF,               // Xllp Scan Code 0x5B
    0xFF,               // Xllp Scan Code 0x5C
    0xFF,               // Xllp Scan Code 0x5D
    0xFF,               // Xllp Scan Code 0x5E
    0xFF,               // Xllp Scan Code 0x5F
    0x40,//VK_TTALK-->VK_SEND       // Xllp Scan Code 0x60     //Is it really like this?
    0x37,//VK_TBACK,     // Xllp Scan Code 0x61 
    0x3D,//VK_TSOFT1,   // Xllp Scan Code 0x62 
    0x3E,//VK_TSOFT2,   // Xllp Scan Code 0x63
    0x36,//VK_TACTION-->Scroll Push,    // Xllp Scan Code 0x64
    0xFF,               // Xllp Scan Code 0x65
    0xFF,               // Xllp Scan Code 0x66
    0xFF,               // Xllp Scan Code 0x67
    0xFF,               // Xllp Scan Code 0x68
    0xFF,               // Xllp Scan Code 0x69
    0xFF,               // Xllp Scan Code 0x6A
    0xFF,               // Xllp Scan Code 0x6B
    0xFF,               // Xllp Scan Code 0x6C
    0xFF,               // Xllp Scan Code 0x6D
    0xFF,               // Xllp Scan Code 0x6E
    0xFF,               // Xllp Scan Code 0x6F
    0x81,//VK_T1,           // Xllp Scan Code 0x70 
    0x84,                  // Xllp Scan Code 0x71
    0x82,//VK_T2,           // Xllp Scan Code 0x72 
    0x85,                  // Xllp Scan Code 0x73
    0x83,//VK_T3,           // Xllp Scan Code 0x74 
    0xFF,               // Xllp Scan Code 0x75
    0xA,                       // Xllp Scan Code 0x76
    0xFF,               // Xllp Scan Code 0x77
    0xFF,               // Xllp Scan Code 0x78
    0xFF,               // Xllp Scan Code 0x79
    0xFF,               // Xllp Scan Code 0x7A
    0xFF,               // Xllp Scan Code 0x7B
    0xFF,               // Xllp Scan Code 0x7C
    0xFF,               // Xllp Scan Code 0x7D
    0xFF,               // Xllp Scan Code 0x7E
    0xFF,               // Xllp Scan Code 0x7F      
    0x84,//VK_T4,           // Xllp Scan Code 0x80      
    0x86,                  // Xllp Scan Code 0x81       
    0x85,//VK_T5,           // Xllp Scan Code 0x82      
    0x87,                  // Xllp Scan Code 0x83
    0x86,//VK_T6,           // Xllp Scan Code 0x84         
    0xFF,               // Xllp Scan Code 0x85
    0xFF,               // Xllp Scan Code 0x86
    0xFF,               // Xllp Scan Code 0x87
    0xFF,               // Xllp Scan Code 0x88
    0xFF,               // Xllp Scan Code 0x89
    0xFF,               // Xllp Scan Code 0x8A
    0xFF,               // Xllp Scan Code 0x8B
    0xFF,               // Xllp Scan Code 0x8C
    0xFF,               // Xllp Scan Code 0x8D
    0xFF,               // Xllp Scan Code 0x8E
    0xFF,               // Xllp Scan Code 0x8F
    0x87,//VK_T7,              // Xllp Scan Code 0x90       
    0xFF,               // Xllp Scan Code 0x91  
    0x88,//VK_T8,              // Xllp Scan Code 0x92   
    0x89,                     // Xllp Scan Code 0x93
    0x89,//VK_T9,              // Xllp Scan Code 0x94
    0xFF,               // Xllp Scan Code 0x95
    0xFF,               // Xllp Scan Code 0x96
    0xFF,               // Xllp Scan Code 0x97
    0xFF,               // Xllp Scan Code 0x98
    0xFF,               // Xllp Scan Code 0x99
    0xFF,               // Xllp Scan Code 0x9A
    0xFF,               // Xllp Scan Code 0x9B
    0xFF,               // Xllp Scan Code 0x9C
    0xFF,               // Xllp Scan Code 0x9D
    0xFF,               // Xllp Scan Code 0x9E
    0xFF,               // Xllp Scan Code 0x9F  
    0x8C,//VK_TSTAR,      // Xllp Scan Code 0xA0        
    0xFF,//VK_APOSTROPHE,   // Xllp Scan Code 0xA1
    0x80,//VK_T0             // Xllp Scan Code 0xA2
    0x8A,                  // Xllp Scan Code 0xA3
    0x8D,//VK_TPOUND        // Xllp Scan Code 0xA4
    0xFF,           // Xllp Scan Code 0xA5
    0xFF,           // Xllp Scan Code 0xA6
    0xFF,           // Xllp Scan Code 0xA7
    0xFF,           // Xllp Scan Code 0xA8
    0xFF,           // Xllp Scan Code 0xA9
    0xFF,           // Xllp Scan Code 0xAA
    0xFF,           // Xllp Scan Code 0xAB
    0xFF,           // Xllp Scan Code 0xAC
    0xFF,           // Xllp Scan Code 0xAD
    0xFF,           // Xllp Scan Code 0xAE
    0xFF,           // Xllp Scan Code 0xAF

    0x8B,              // Xllp Scan Code 0xB0       
    0x8C,                 // Xllp Scan Code 0xB1        
    0x31,//VK_BACK     // Xllp Scan Code 0xB2       
    0x8D,                 // Xllp Scan Code 0xB3
    0x8F,//VK_DELETE VK_ENTER   // Xllp Scan Code 0xB4
    0xFF,           // Xllp Scan Code 0xB5
    0xFF,           // Xllp Scan Code 0xB6
    0xFF,           // Xllp Scan Code 0xB7
    0xFF,           // Xllp Scan Code 0xB8
    0xFF,           // Xllp Scan Code 0xB9
    0xFF,           // Xllp Scan Code 0xBA
    0xFF,           // Xllp Scan Code 0xBB
    0xFF,           // Xllp Scan Code 0xBC
    0xFF,           // Xllp Scan Code 0xBD
    0xFF,           // Xllp Scan Code 0xBE
    0xFF,           // Xllp Scan Code 0xBF

    
};  //XllpScanCodeToWinCeScanCodeTable[]

#define MainScanCodeTableFirst 0x00
#define MainScanCodeTableLast       0x4F
#define MAIN_SCAN_CODE_TABLE_SIZE ((MainScanCodeTableLast-MainScanCodeTableFirst)+1)

const UINT8  MainScanCodeToVKeyTable[MAIN_SCAN_CODE_TABLE_SIZE] =
{
    //uiVK              //uiSC
    VK_T0          , //     0x00
    VK_T1          , //     0x01
    VK_T2          , //     0x02
    VK_T3          , //     0x03
    VK_T4          , //     0x04
    VK_T5          , //     0x05
    VK_T6          , //     0x06
    VK_T7          , //     0x07
    VK_T8          , //     0x08
    VK_T9          , //     0x09
    0              , //     0x0A 
    0              , //     0x0B
    0              , //     0x0C
    0              , //     0x0D
    0              , //     0x0E
    0              , //     0x0F
    'A'            , //     0x10
    'B'            , //     0x11
    'C'            , //     0x12
    'D'            , //     0x13
    'E'            , //     0x14
    'F'            , //     0x15
    'G'            , //     0x16
    'H'            , //     0x17
    'I'                   , //     0x18
    'J'                   , //     0x19
    'K'            , //     0x1A
    'L'            , //     0x1B
    'M'            , //     0x1C
    'N'            , //     0x1D
    'O'            , //     0x1E
    'P'            , //     0x1F
    'Q'            , //     0x20
    'R'            , //     0x21
    'S'            , //     0x22
    'T'            , //     0x23
    'U'            , //     0x24
    'V'            , //     0x25
    'W'            , //     0x26
    'X'            , //     0x27
    'Y'            , //     0x28
    'Z'            , //     0x29
    0              , //     0x2A 
    0              , //     0x2B
    0              , //     0x2C
    0              , //     0x2D
    0              , //     0x2E
    0              , //     0x2F
    0              , //     0x30
    VK_BACK    , //          0x31
    VK_CAPITAL  , //        0x32
    VK_CONTROL,//       0x33
    VK_TRIGHT      ,//      0x34
    VK_SPACE       , //     0x35
    VK_RETURN   ,//     0x36  equal to VK_TACTION
    VK_TBACK       , //     0x37
    VK_TDOWN       , //     0x38
    VK_TEND    , //     0x39
    VK_THOME       , //     0x3A
    VK_TLEFT       , //     0x3B
    VK_TPOUND  , //     0x3C
    VK_TSOFT1      , //     0x3D
    VK_TSOFT2      , //     0x3E
    VK_TSTAR       , //     0x3F
    VK_TTALK       , //     0x40
    VK_TUP     , //     0x41
    VK_TVOLUMEDOWN, // 0x42
    VK_TVOLUMEUP,      //  0x43
    VK_OFF ,                 //  0x44
    //VK_RECORD,           // 0x45     

}; // MainScanCodeToVKeyTable[]

//------------------------------------------------------------------------------

BOOL
BootKeypadLittletonInit(
    VOID* pContext,
    DWORD contextSize,
    BOOT_DEVICE_IFC **ppIfc
    )
{
    BOOL rc = FALSE;

    // Check parameter
    if (ppIfc == NULL) goto cleanUp;
    *ppIfc = NULL;

    // Create store context
    memset(&s_keypad, 0, sizeof(KEYPAD));
    s_keypad.cookie = KEYPAD_COOKIE;

    // Clocks
    XllpClockEnable((P_XLLP_CLKMGR_T)g_vpClkRegs, XLLP_CLK_KEYPAD, XLLP_TRUE);

    // Pins
    if (!g_MfpRmDbInitialized && XLLP_STATUS_SUCCESS != XllpMfpResourceManagerInit(g_pMfpRmDb)) {
        OALMSG(OAL_ERROR, (L"ERROR: IPL Keypad driver failed in XllpMfpResourceManagerInit()\r\n"));
        goto cleanUp;
    } else {
        g_MfpRmDbInitialized = TRUE;
    }

    // Registers
    if (XLLP_STATUS_SUCCESS != XllpKeyPadConfigure ( (XLLP_KEYPAD_REGS *)g_vpKeypadRegs, (P_XLLP_VUINT32_T)g_vpMFPRegs, g_pMfpRmDb, XLLP_TRUE, 0, 0)) {
        OALMSG(OAL_ERROR, (L"ERROR: IPL Keypad driver failed in XllpKeyPadConfigure()\r\n"));
        goto cleanUp;
    }

    // Done
    *ppIfc = &s_keypadIfc;
    rc = TRUE;

cleanUp:
    if (!rc) BootKeypadLittletonDeinit(&s_keypad);
    return rc;
}

//------------------------------------------------------------------------------

BOOL
BootKeypadLittletonDeinit(
    HANDLE hKeypad
    )
{
    BOOL rc = FALSE;
    KEYPAD *pKeypad = (KEYPAD*)hKeypad;

    // Check display handle
    if ((pKeypad == NULL) || (pKeypad->cookie != KEYPAD_COOKIE))
        {
        OALMSG(OAL_ERROR, (L"ERROR: BootKeypadLittletonDeinit: "
            L"Invalid keypad handle!\r\n"
            ));
        goto cleanUp;
        }

    // Not sure what deinitialization can really be done

    // Done
    rc = TRUE;

cleanUp:
    return rc;
}

//------------------------------------------------------------------------------

BOOL
BootKeypadLittletonIoCtl(
    HANDLE hKeypad,
    DWORD code,
    VOID* pBuffer,
    DWORD size
    )
{
    BOOL rc = FALSE;
    KEYPAD *pKeypad = (KEYPAD*)hKeypad;

    // Check display handle
    if ((pKeypad == NULL) || (pKeypad->cookie != KEYPAD_COOKIE))
        {
        OALMSG(OAL_ERROR, (L"ERROR: BootKeypadLittletonIoCtl: "
            L"Invalid keypad handle!\r\n"
            ));
        goto cleanUp;
        }

    switch (code)
        {
        case BOOT_KEYPAD_IOCTL_ISPRESSED:
            {
            // Check input parameter
            if (pBuffer == NULL || size < sizeof(UINT16))
                {
                OALMSG(OAL_ERROR, (L"ERROR: BootKeypadLittletonIoCtl: "
                    L"BOOT_KEYPAD_IOCTL_ISPRESSED - Invalid parameters!\r\n"
                    ));
                break;
                }
            rc = KeypadPressed(pKeypad, *(UINT16*)pBuffer);
            }
            break;
        case BOOT_KEYPAD_IOCTL_SCAN4KEYS:
        case BOOT_KEYPAD_IOCTL_GETPROPS:
            OALMSG(OAL_ERROR, (L"ERROR: BootKeypadMSM7500IoCtl: "
                L"IOCTL Unsupported\r\n"
                ));
            break;
        }

cleanUp:
    return rc;
}

//------------------------------------------------------------------------------

static
BOOL
KeypadPressed(
    KEYPAD* pKeypad,
    UINT16 vk
    )
{
    UINT8 MatrixScanCode = NO_KEY;
    UINT8 XllpScanCode;
    UINT8 MainScanCode;
    XLLP_KEYPAD_REGS * pKeyRegs = (XLLP_KEYPAD_REGS *) g_vpKeypadRegs;

    UINT8 keys[35];
    UINT32 num_of_keys_pressed;

    num_of_keys_pressed=0;

    //Check parameter
    if (0 == vk) goto cleanUp;

    read_scan_code_automatically(pKeyRegs, &num_of_keys_pressed, keys);

    MatrixScanCode = keys[0];


    //Convert into an XLLP key
    if( MatrixScanCode >= dimof(MatrixToXllpScanCodeTable) ) goto cleanUp;
    XllpScanCode = MatrixToXllpScanCodeTable[MatrixScanCode];

    // Convert into a PS2 keyboard key
    if( XllpScanCode >= dimof(XllpScanCodeToMainScanCodeTable)) goto cleanUp;
    MainScanCode = XllpScanCodeToMainScanCodeTable[XllpScanCode];

    // Convert into a Windows CE virtual key
    if( MainScanCode >= dimof(MainScanCodeToVKeyTable) ) goto cleanUp;
    if( vk == MainScanCodeToVKeyTable[MainScanCode] ) return TRUE;

cleanUp:
    return FALSE;
}

//------------------------------------------------------------------------------


